/*
Philip Dilse
dilsep
Assignment 4

random tester for adventurer card
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>

#include "dominion.h"
#include "dominion_helpers.h"

#define NUMTESTS 20
#define HANDSIZE 5
#define DECK_AND_DISCARD_SIZE 35

static jmp_buf env;

void handler(int sig) {
    printf("handler\n");
    longjmp(env, 1);
}

int main() {
    int test, i;
    int player = 0;
    int handPos = 0;

    struct gameState *gs = newGame();

    gs->whoseTurn = player; 
    
    // set up random number gen
    srand(time(NULL));

    // set up signal handler
    signal(SIGALRM, handler);
    
    for (test = 0; test < NUMTESTS; test++) {
        int numTreasure = 0;

        // deck count between 0 and DECK_AND_DISCARD_SIZE
        gs->deckCount[player] = rand() % (DECK_AND_DISCARD_SIZE + 1);
        
        // deck + discard count = DECK_AND_DISCARD_SIZE
        gs->discardCount[player] = DECK_AND_DISCARD_SIZE - gs->deckCount[player];

        gs->handCount[player] = HANDSIZE;

        // place adventurer card at hand[0] and curses at the other spots
        gs->hand[player][handPos] = adventurer;
        for (i = 1; i < gs->deckCount[player]; i++) {
            gs->hand[player][i] = curse;
        }
       
        // randomly select deck cards
        for (i = 0; i < gs->deckCount[player]; i++) {
            gs->deck[player][i] = rand() % (treasure_map + 1);
            int card = gs->deck[player][i];
            if (numTreasure < 2 && (card == copper || card == silver || card == gold)) {
                numTreasure++;
            }
        }
        
        // randomly select discard cards
        for (i = 0; i < gs->discardCount[player]; i++) {
            gs->discard[player][i] = rand() % (treasure_map + 1);
            int card = gs->discard[player][i];
            if (numTreasure < 2 && (card == copper || card == silver || card == gold)) {
                numTreasure++;
            }
        }
        
        // start timer to abort infinite loop, 1 second
        alarm(1);

        if (setjmp(env) == 0) {
	    printf("treasures=%d\n", numTreasure);
            cardEffect(adventurer, 0, 0, 0, gs, handPos, &i);
            alarm(0);
        } else {
            printf("adventurer_effect() error: appears to be in an infinite loop; numTreasures=%d\n", numTreasure);
        }

        // check that hand count is correct, -1 from played adventurer card
        if (gs->handCount[player] != HANDSIZE - 1 + numTreasure) {
            printf("adventurer_effect() error: handCount incorrect; expected=%d actual=%d\n", HANDSIZE - 1 + numTreasure, gs->handCount[player]);
        }
        
        // check that top numTreasure cards in hand equal treasure
        for (i = gs->handCount[player] - 1; i > gs->handCount[player] - 1 - numTreasure; i--) {
            int card = gs->hand[player][i];
            if (card != copper && card != silver && card != gold) {
                printf("adventurer_effect() error: treasure not in hand; position=%d card=%d", i, card);
            }
        }
    }

    free(gs);
    return 0;
}
